﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace NLE
{
    public class UndoHandler
    {

        public Stack<Action> UndoList { get; set; }
        public Stack<Action> RedoList { get; set; }

        private ImageControl Parent { get; set; }

        public UndoHandler(ImageControl pParent)
        {

            Parent = pParent;

            UndoList = new Stack<Action>();
            RedoList = new Stack<Action>();

        }

        public void DoUndo()
        {
            if (UndoList.Count == 0) return;

            // Get the last action
            Action lastAction = UndoList.Pop();

            // Add to the redo list
            RedoList.Push(lastAction);

            // Undo it
            switch (lastAction.Type)
            {
                case Action.ActionType.Creation:
                    Parent.DeleteObject(lastAction.Object);
                    //lastAction.Object.Layer.LevelObjects.Remove(lastAction.Object);
                    break;
                case Action.ActionType.Deletion:
                    Parent.AddToLayer(lastAction.Object.Layer, lastAction.Object);
                    //lastAction.Object.Layer.LevelObjects.Add(lastAction.Object);
                    break;
                case Action.ActionType.Translation:
                    lastAction.Object.Position = lastAction.OldPosition;
                    break;
                case Action.ActionType.Rotation:
                    lastAction.Object.Rotation = lastAction.OldRotation;
                    break;
                case Action.ActionType.Scale:
                    lastAction.Object.Scale = lastAction.OldScale;
                    break;
                case Action.ActionType.PropertyChange:
                    if (lastAction.Object == null)
                    {
                        Parent.Properties[lastAction.Property] = lastAction.OldPropertyValue;
                        Parent.SetPropertiesForLevel();
                    }
                    else
                    {
                        lastAction.Object.Properties[lastAction.Property] = lastAction.OldPropertyValue;
                    }
                    break;
                case Action.ActionType.OriginChange:
                    lastAction.Object.Origin = lastAction.OldOrigin;
                    break;
                default:
                    break;
            }
        }

        public void DoRedo()
        {

            if (RedoList.Count == 0) return;

            // Get the redo action
            Action redoAction = RedoList.Pop();

            // Add it to the undo list
            UndoList.Push(redoAction);

            // Redo it
            switch (redoAction.Type)
            {
                case Action.ActionType.Creation:
                    Parent.AddToLayer(redoAction.Object.Layer, redoAction.Object);
                    //redoAction.Object.Layer.LevelObjects.Add(redoAction.Object);
                    break;
                case Action.ActionType.Deletion:
                    Parent.DeleteObject(redoAction.Object);
                    //redoAction.Object.Layer.LevelObjects.Remove(redoAction.Object);
                    break;
                case Action.ActionType.Translation:
                    redoAction.Object.Position = redoAction.NewPosition;
                    break;
                case Action.ActionType.Rotation:
                    redoAction.Object.Rotation = redoAction.NewRotation;
                    break;
                case Action.ActionType.Scale:
                    redoAction.Object.Scale = redoAction.NewScale;
                    break;
                case Action.ActionType.PropertyChange:
                    if (redoAction.Object == null)
                    {
                        Parent.Properties[redoAction.Property] = redoAction.NewPropertyValue;
                        Parent.SetPropertiesForLevel();
                    }
                    else
                    {
                        redoAction.Object.Properties[redoAction.Property] = redoAction.NewPropertyValue;
                    }
                    break;
                case Action.ActionType.OriginChange:
                    redoAction.Object.Origin = redoAction.NewOrigin;
                    break;
                default:
                    break;
            }

        }
    }
}
